#include <common/logger/logger.h>
#include <private/table/cxigroupproxy.h>
CxiGroupProxy::CxiGroupProxy(QObject* parent)
	: QAbstractProxyModel(parent)
{
}

CxiGroupProxy::~CxiGroupProxy()
{
}

void CxiGroupProxy::addGroupConfigs(const QList<cxitable::GroupConfig>& configs)
{
	beginResetModel();
	m_groupConfigs = configs;
	rebuildGroups();
	endResetModel();
}

void CxiGroupProxy::addGroupConfig(const cxitable::GroupConfig& config)
{
	if (!hasGroupColumn(config.column))
	{
		beginResetModel();
		m_groupConfigs.append(config);
		rebuildGroups();
		endResetModel();
	}
}

void CxiGroupProxy::removeGroupConfig(const cxitable::GroupConfig& config)
{
	int index = findGroupIndex(config.column);
	if (index != -1)
	{
		beginResetModel();
		m_groupConfigs.removeAt(index);
		rebuildGroups();
		endResetModel();
	}
}

void CxiGroupProxy::removeGroupColumn(int column)
{
	int index = findGroupIndex(column);
	if (index != -1)
	{
		beginResetModel();
		m_groupConfigs.removeAt(index);
		rebuildGroups();
		endResetModel();
	}
}

void CxiGroupProxy::removeGroupColumns(const QList<int>& columns)
{
	for (const auto& column: columns)
	{
		removeGroupColumn(column);
	}
}

QVector<int> CxiGroupProxy::groupColumns() const
{
	QVector<int> cols;
	cols.reserve(m_groupConfigs.size());
	for (const auto& cfg: m_groupConfigs) cols.append(cfg.column);
	return cols;
}

QList<cxitable::GroupConfig> CxiGroupProxy::groupConfigs() const
{
	return m_groupConfigs;
}

void CxiGroupProxy::flushGroup()
{
	beginResetModel();
	rebuildGroups();
	endResetModel();
}

QModelIndex CxiGroupProxy::index(int row, int column, const QModelIndex& parent) const
{
	if (!hasIndex(row, column, parent))
		return {};

	// 顶层组（无父项）
	if (!parent.isValid())
	{
		if (row < m_groups.size())
			return createIndex(row, column, m_groups[row]);
		// 非法访问
		LOG_WARN("顶层分组索引行溢出");
		return {};
	}

	if (const auto parentGroupData = static_cast<GroupData*>(parent.internalPointer()))
		return createIndex(row, column, parentGroupData->subGroups[row]);

	LOG_WARN("模型数据异常");
	return {};
}

QVariant CxiGroupProxy::data(const QModelIndex& index, int role) const
{
	if (!index.isValid() || !sourceModel())
		return {};

	const GroupData* group = static_cast<const GroupData*>(index.internalPointer());

	if (!group) return {};

	if (group->type == GroupData::LeafGroup)
	{
		int sourceRow = group->sourceRows.first();
		const QModelIndex sourceIndex = sourceModel()->index(sourceRow, index.column());
		return sourceModel()->data(sourceIndex, role);
	}
	if (group->type == GroupData::SubGroup)
	{
		// TODO：可以根据需求调整分组显示效果
		if (group->level >= 0 && index.column() == 0 && role == Qt::DisplayRole)
			return group->groupName;
		return {};
	}
	LOG_WARN("数据映射异常，检查逻辑");
	return {};
}

bool CxiGroupProxy::setData(const QModelIndex& index, const QVariant& value, int role)
{
	if (!index.isValid() || !sourceModel())
		return false;
	auto* group = static_cast<const GroupData*>(index.internalPointer());

	if (!group)
		return false;

	// 叶子节点进行赋值，非叶子不处理
	if (group->type == GroupData::LeafGroup)
	{
		const int sourceRow = group->sourceRows.first();
		const auto sourceIndex = sourceModel()->index(sourceRow, index.column());
		return sourceModel()->setData(sourceIndex, value, role);
	}
	return false;
}

QModelIndex CxiGroupProxy::mapFromSource(const QModelIndex& sourceIndex) const
{
	if (!sourceIndex.isValid() || !sourceModel())
		return {};

	// 拷贝一个查询队列
	QVector<GroupData*> groups = m_groups;

	while (!groups.empty())
	{
		auto* group = groups.takeFirst();

		if (!group->sourceRows.contains(sourceIndex.row()))
			continue;

		if (group->type == GroupData::SubGroup)
		{
			if (!group->subGroups.empty()) groups.append(group->subGroups);
		}
		else if (group->type == GroupData::LeafGroup)
		{
			const auto parentGroup = group->parent;
			int rowInParent = parentGroup->subGroups.indexOf(group);
			if (rowInParent != -1) {
				return createIndex(rowInParent, sourceIndex.column(), group);
			}
		}
	}
	return {};
}

QModelIndex CxiGroupProxy::mapToSource(const QModelIndex& proxyIndex) const
{
	if (!proxyIndex.isValid() || !sourceModel())
		return {};

	const auto* group = static_cast<const GroupData*>(proxyIndex.internalPointer());

	if (!group) return {};

	if (group->type == GroupData::LeafGroup)
	{
		const int sourceRow = group->sourceRows.first();
		return sourceModel()->index(sourceRow, proxyIndex.column());
	}
	// 分组行不对应实际数据无需处理
	return {};
}

void CxiGroupProxy::setSourceModel(QAbstractItemModel* sourceModel)
{
	QAbstractProxyModel::setSourceModel(sourceModel);
}

QModelIndex CxiGroupProxy::parent(const QModelIndex& index) const
{
	if (!index.isValid()) return {};
	auto* group = static_cast<const GroupData*>(index.internalPointer());
	if (!group) return {};
	const auto parentGroup = group->parent;

	if (!parentGroup)
	{
		return{};
	}
	if (parentGroup->parent == nullptr)
	{
		for (int i = 0; i < m_groups.size(); ++i) {
			if (m_groups[i] == parentGroup) {
				return createIndex(i, 0, parentGroup);
			}
		}
	}
	else {
		const auto grandparentGroup = parentGroup->parent;
		// 查找父组在祖父组中的索引
		for (int i = 0; i < grandparentGroup->subGroups.size(); ++i) {
			if (grandparentGroup->subGroups[i] == parentGroup) {
				return createIndex(i, 0, parentGroup);
			}
		}
	}

	return {};
}

QVariant CxiGroupProxy::headerData(int section, Qt::Orientation orientation, int role) const
{
	if (!sourceModel())
		return QVariant();

	return sourceModel()->headerData(section, orientation, role);
}

bool CxiGroupProxy::setHeaderData(int section, Qt::Orientation orientation, const QVariant& value, int role)
{
	if (!sourceModel())
		return false;

	return sourceModel()->setHeaderData(section, orientation, value, role);
}
int CxiGroupProxy::rowCount(const QModelIndex& parent) const
{
	if (!sourceModel())
		return 0;
	if (!parent.isValid())
		return m_groups.size();
	if (parent.internalPointer() == nullptr)
	{
		return 0;
	}

	auto parentGroup = static_cast<const GroupData*>(parent.internalPointer());

	if (parentGroup->type == GroupData::SubGroup)
	{
		// 如果有子组，返回子组数
		if (!parentGroup->subGroups.isEmpty())
		{
			return parentGroup->subGroups.size();
		}
		// 否则返回组内项数(LeafGroup)
		return parentGroup->sourceRows.size();
	}
	return 0;
}
int CxiGroupProxy::columnCount(const QModelIndex& parent) const
{
	if (!sourceModel())
		return 0;

	// 直接调用源模型接口
	return sourceModel()->columnCount(mapToSource(parent));
}

void CxiGroupProxy::rebuildGroups()
{
	qDeleteAll(m_groups);
	m_groups.clear();

	if (!sourceModel() || m_groupConfigs.isEmpty()) return;

	int sourceRowCount = sourceModel()->rowCount();

	// 创建根节点
	auto* rootGroup = new GroupData();
	rootGroup->level = -1;
	rootGroup->column = -1;
	rootGroup->type = GroupData::RootGroup;
	rootGroup->parent = nullptr;
	for (int sourceRow = 0; sourceRow < sourceRowCount; ++sourceRow)
	{
		rootGroup->sourceRows.append(sourceRow);
	}

	// 递归构建多层级分组
	buildGroupsRecursive(rootGroup, 0, sourceRowCount);

	// 根节点的子节点成为顶层分组
	m_groups.clear();
	while (!rootGroup->subGroups.isEmpty())
	{
		m_groups.append(rootGroup->subGroups.takeFirst());
	}

	// 释放根节点（它的子节点已经移交给m_groups）
	delete rootGroup;
}

void CxiGroupProxy::buildGroupsRecursive(GroupData* parentGroup, int level, int endRow)
{
	if (level >= m_groupConfigs.size())
	{
		const auto leafRows = parentGroup->sourceRows;
		for (int leafRow: leafRows)
		{
			auto subgroup = new GroupData();
			subgroup->type = GroupData::LeafGroup;
			subgroup->level = level;
			subgroup->parent = parentGroup;
			subgroup->sourceRows.push_back(leafRow);
			parentGroup->subGroups.append(subgroup);
		}
		return;
	}
	const auto &config = m_groupConfigs[level];
	int column = config.column;
	QMap<QString, QVector<int>> valueRowsMap;

	// const QVector<int>& rows = parentGroup->sourceRows.isEmpty()
	// ? getAllRows(0,endRow) : parentGroup->sourceRows;
	const QVector<int>& rows = parentGroup->sourceRows;

	for (int row: rows)
	{
		auto index = sourceModel()->index(row, column);
		QVariant data = sourceModel()->data(index);
		QString value = data.toString();
		valueRowsMap[value].append(row);
	}

	// 为每个唯一值创建子组
	for (auto it = valueRowsMap.begin(); it != valueRowsMap.end(); ++it)
	{
		GroupData* subgroup = new GroupData();
		subgroup->level = level;
		subgroup->column = column;
		subgroup->sourceRows = it.value();
		subgroup->type = GroupData::SubGroup;
		if (level > 0)
		{
			subgroup->parent = parentGroup;
		}

		// 设置组名
		QVariant headerData = sourceModel()
									  ->headerData(column, Qt::Horizontal);

		if (headerData.isValid())
		{
			subgroup->groupName = formatGroupTitle(config, headerData.toString(), it.key(), it.value().size());
		}
		else
		{
			subgroup->groupName = it.key();
		}

		// 递归构建下一级分组
		buildGroupsRecursive(subgroup, level + 1, endRow);

		parentGroup->subGroups.append(subgroup);
	}
}

bool CxiGroupProxy::hasGroupColumn(int column) const
{
	return std::any_of(m_groupConfigs.begin(), m_groupConfigs.end(),
	                   [column](const auto& cfg) { return cfg.column == column; });
}

int CxiGroupProxy::findGroupIndex(int column) const
{
	for (int i = 0; i < m_groupConfigs.size(); ++i)
	{
		if (m_groupConfigs[i].column == column) return i;
	}
	return -1;
}

QString CxiGroupProxy::formatGroupTitle(const cxitable::GroupConfig& config, const QString& title, const QString& data, int count)
{
	QString result = config.groupTitle;
	result.replace(cxitable::TITLE, title);
	result.replace(cxitable::DATA, data);
	result.replace(cxitable::COUNT, QString::number(count));
	return result;
}